package de.hsb.ai.agent.misterx.brain;

import game.Move;
import jade.core.AID;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import de.hsb.ai.agent.misterx.Drawer;
import de.hsb.ai.agent.misterx.brain.geoanalyser.GeoAnalyser;
import de.hsb.ai.agent.misterx.brain.history.HistoryCapturer;
import de.hsb.ai.domain.GameOver;
import de.hsb.ai.domain.GameStarted;
import de.hsb.ai.domain.MoveEvent;
import de.hsb.ai.util.map.ScotlandJadeMap;

public class Brain implements IHandle {

	public static HistoryCapturer HISTORYCAPTURER;
	public static GraphAnalyser GRAPHANALYSER;
	public static ScotlandJadeMap SCOTLANDJADEMAP;
	public static GeoAnalyser GEOANALYSER;
	
	private static AID AID;
	private static List<AID> AIDS = new ArrayList<AID>();
	
	private static int CURRENTROUND = 0;

	
	public Brain(AID aid, ScotlandJadeMap map) {
		AID = aid;
		SCOTLANDJADEMAP = map;
		
		HISTORYCAPTURER = new HistoryCapturer();
		GRAPHANALYSER = new GraphAnalyser(map);
		GEOANALYSER = new GeoAnalyser();
	}

	@Override
	public void handleGameStarted(GameStarted g) {
		HISTORYCAPTURER.handleGameStarted(g);
		AIDS = g.getInfo().getPlayers();
	}

	@Override
	public void handleGameOver(GameOver g) {
		
	}

	@Override
	public void handleMove(MoveEvent m) {
		HISTORYCAPTURER.handleMove(m);
		CURRENTROUND = m.getRound();
	}

	@Override
	public Move getMove(List<Move> options) {
		Drawer.addVisible(Brain.isMrXVisible());
		GRAPHANALYSER.update(20);
		GEOANALYSER.update();
		return null;
	}
	
//////////////////////////////////////////////////////////////////////////////////////////////
// 
//////////////////////////////////////////////////////////////////////////////////////////////
	
	/**
	 * gibt die eigene AIDs zurück.
	 * @return
	 */
	public static AID getOwnAID() {
		return AID;
	}
	
	/**
	 * gibt die AIDs aller Feinde zurück.
	 * @return
	 */
	public static List<AID> getEnemyAIDs() {
		List<AID> aids = new ArrayList<AID>();
		for(AID aid : AIDS) {
			if(aid.equals(AID) == false) {
				aids.add(aid);
			}
		}
		
		return aids;
	}
	
	public static int getEnemyCount() {
		return AIDS.size() -1;
	}

	/**
	 * gibt die AIDs aller Spieler zurück.
	 * @return
	 */
	public static List<AID> getAllAIDs() {
		return AIDS;
	}
	

	/**
	 * gibt die nächste Runde zurück in der man sichtbar ist.
	 * TODO: noch nicht getestet.
	 * @return
	 */
	public int getNextVisibleRound() {
		return CURRENTROUND + ((CURRENTROUND - 3) % 5);
	}
	
	/**
	 * gibt die Anzahl der Runden zurück bis man sichtbar wird.
	 * TODO: noch nicht getestet.
	 * @return
	 */
	public int getRoundCountUntilVisible() {
		return (CURRENTROUND - 3) % 5;
	}
	
	public static int getCurrentRound() {
		return CURRENTROUND;
	}
	
//////////////////////////////////////////////////////////////////////////////////////////////
// MOOD TRIGGER
//////////////////////////////////////////////////////////////////////////////////////////////
	
	/**
	 * prüft ob ein Feind gegen einen antritt.
	 */
	public static boolean isEnemyOne() {
		return AIDS.size() == 2;
	}
	
	/**
	 * prüft ob zwei Feinde gegen einen antretten.
	 */
	public static boolean isEnemyTwo() {
		return AIDS.size() == 3;
	}
	
	/**
	 * prüft ob mehr als zwei Feinde gegen einen antretten.
	 * @return
	 */
	public static boolean isEnemyMulti() {
		return AIDS.size() > 3;
	}
	
	/**
	 * prüft ob MrX zur Zeit sichtbar ist.
	 * @return
	 */
	public static boolean isMrXVisible() {
		return ((CURRENTROUND - 3) % 5) == 0;
	}
	
	/**
	 * prüft ob Mrx zwischen der aufspannenden Fläche der Gegner sich befindet.
	 * @return
	 */
	public static boolean isMrXBetweenEnemies() {
		return GEOANALYSER.isInConvexHull();
	}
	
	/**
	 * prüft ob die aufspannenden Fläche ründlich ist.
	 * @return
	 */
	public static boolean isEnemyAreaRound() {
		double roundfactor = GEOANALYSER.getCurrentConvexHullExzentrität();
		if(roundfactor < 4) {
			return true;
		} else {
			return false;
		}
		
	}
	
	/**
	 * prüft ob die aufspannene Fläche der Feinde als Groß erachtet wird .
	 * @return
	 */
	public static boolean isEnemyAreaBig() {
		return (GEOANALYSER.getCurrentConvexHullArea() > 15);
	}
	
	public static boolean isMrXLeftQuadrant() {
		int[] quadrant = GEOANALYSER.getCurrentQaudrant(AID);
		return quadrant[1] == 0;
	}
	
	public static boolean isMrXTopQuadrant() {
		int[] quadrant = GEOANALYSER.getCurrentQaudrant(AID);
		return quadrant[0] == 0;
	}
	
	public static boolean isConvexHullCentroidLeft() {
		Point2D position = GEOANALYSER.getCurrentConvexHullCentroid();
		int[] quadrant = GEOANALYSER.getQuadrant(position, 2, 2);
		return quadrant[1] == 0;
	}
	
	public static boolean isConvexHullCentroidTop() {
		Point2D position = GEOANALYSER.getCurrentConvexHullCentroid();
		int[] quadrant = GEOANALYSER.getQuadrant(position, 2, 2);
		return quadrant[0] == 0;
	}
	
//////////////////////////////////////////////////////////////////////////////////////////////
// FUINKTIONS
//////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * gibt die Anzahl der Feinde im Quadranten zurück. (fixe Größe 2x2)
	 */
	public int getQuadrantEnemyCount(int i, int j) {
		return GEOANALYSER.getQaudrantEnemyCount()[i][j];
	}
	
	/**
	 * gibt die Anzahl der Feinde im Quadranten zurück. (variables Grid)
	 */
	public int getQuadrantEnemyCount(int i, int j, int splitX, int splitY) {
		return GEOANALYSER.getQaudrantEnemyCount(splitX, splitY)[i][j];
	}
	
	public Move getOwnLastMove() {
		return HISTORYCAPTURER.getLastPlayerMove(AID);
	}
	
	
}
